package com.example.myapplication.livedata.fragment;

import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LifecycleRegistry;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.myapplication.R;
import com.example.myapplication.databinding.FragmentLiveDataLifecycleBinding;
import com.example.myapplication.navigation.fragment.BaseLifeFragment;

import java.util.HashMap;

/**
 * A simple {@link Fragment} subclass.
 * create an instance of this fragment.
 *
 * @see <a href="https://developer.android.com/topic/libraries/architecture/lifecycle?hl=zh-cn">官方文档</a>
 */
public class LiveDataLifecycleFragment extends BaseLifeFragment {

    private FragmentLiveDataLifecycleBinding binding;
    private static final String TAG = "LiveDataLifecycleFragment";
    private MineLifecycleOwner mineLifecycleOwner;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = FragmentLiveDataLifecycleBinding.inflate(getLayoutInflater());
        mineLifecycleOwner = new MineLifecycleOwner();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return binding.getRoot();
    }


    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initEvent();

    }

    @Override
    public String initLogHead() {
        return "";
    }

    @Override
    public String getLogTag() {
        return TAG;
    }

    private void initEvent() {
        binding.ldLifecycleBtnAddListener.setOnClickListener(v -> {
            addLifecycleListener();
        });
        initMineLifecycleEvent();
    }

    private void addLifecycleListener() {
        Lifecycle lifecycle = getLifecycle();
        Log.e(TAG, "addLifecycleListener() " + lifecycle.toString());

        lifecycle.addObserver((LifecycleEventObserver) (source, event) -> {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("LifecycleObserver : onStateChanged() ");
            stringBuilder.append(source.getLifecycle().toString());
            stringBuilder.append("  ");
            stringBuilder.append(source.getLifecycle().getCurrentState().name());
            stringBuilder.append("  ");
            stringBuilder.append(event.getTargetState().name());

            Log.e(TAG, stringBuilder.toString());
        });

        /**
         * 这种的是将LifecycleObserver进行了包装，拆分出对应方法，比较清晰。然后底层使用FullLifecycleObserverAdapter 进行了包装
         * FullLifecycleObserverAdapter 实现了LifecycleEventObserver 接口，然后进行方法的分发。
         * {@link androidx.lifecycle.FullLifecycleObserverAdapter}
         * {@link androidx.lifecycle.LifecycleRegistry#addObserver(LifecycleObserver)}
         * {@link androidx.lifecycle.LifecycleRegistry.ObserverWithState#ObserverWithState(LifecycleObserver observer, Lifecycle.State initialState)
         */

        lifecycle.addObserver(new DefaultLifecycleObserver() {
            @Override
            public void onCreate(@NonNull LifecycleOwner owner) {
                Log.e(TAG, "DefaultLifecycleObserver: onCreate(): " + owner.getLifecycle().getCurrentState().name());
            }

            @Override
            public void onStart(@NonNull LifecycleOwner owner) {
                Log.e(TAG, "DefaultLifecycleObserver: onStart(): " + owner.getLifecycle().getCurrentState().name());
            }

            @Override
            public void onResume(@NonNull LifecycleOwner owner) {
                Log.e(TAG, "DefaultLifecycleObserver: onResume(): " + owner.getLifecycle().getCurrentState().name());
            }

            @Override
            public void onPause(@NonNull LifecycleOwner owner) {
                Log.e(TAG, "DefaultLifecycleObserver: onPause(): " + owner.getLifecycle().getCurrentState().name());
            }

            @Override
            public void onStop(@NonNull LifecycleOwner owner) {
                Log.e(TAG, "DefaultLifecycleObserver: onStop(): " + owner.getLifecycle().getCurrentState().name());
            }

            @Override
            public void onDestroy(@NonNull LifecycleOwner owner) {
                Log.e(TAG, "DefaultLifecycleObserver: onDestroy(): " + owner.getLifecycle().getCurrentState().name());
            }
        });
    }


    private void initMineLifecycleEvent() {
        binding.ldLifecycleBtnAddMineOwner.setOnClickListener(v -> {
            if (binding.cardAddMineOwner.getVisibility() == View.VISIBLE) {
                removeMineLifeCycleObserver();
            } else {
                addMineLifeCycleOwnerObserver();
            }
        });

        binding.btnOnCreate.setOnClickListener(v -> {
            mineLifecycleOwner.onCreate();
        });
        binding.btnOnStart.setOnClickListener(v -> {
            mineLifecycleOwner.onStart();
        });
        binding.btnOnResume.setOnClickListener(v -> {
            mineLifecycleOwner.onResume();
        });
        binding.btnOnDestroy.setOnClickListener(v -> {
            mineLifecycleOwner.onDestroy();
        });
    }

    private void addMineLifeCycleOwnerObserver() {
        binding.cardAddMineOwner.setVisibility(View.VISIBLE);
        binding.ldLifecycleBtnAddMineOwner.setText("移除MineLifecycle监听");
        mineLifecycleOwner.getLifecycle().addObserver(mineLifecycleObserver);
    }

    private void removeMineLifeCycleObserver() {
        binding.cardAddMineOwner.setVisibility(View.GONE);
        binding.ldLifecycleBtnAddMineOwner.setText("添加MineLifecycle监听");
        mineLifecycleOwner.getLifecycle().removeObserver(mineLifecycleObserver);
    }

    /**
     * 自己实现的一个lifecycleOwner
     */
    private LifecycleEventObserver mineLifecycleObserver = new LifecycleEventObserver() {
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {

            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("mineLifecycleObserver : onStateChanged() ");
            stringBuilder.append(source.getLifecycle().toString());
            stringBuilder.append("  ");
            stringBuilder.append(source.getLifecycle().getCurrentState().name());
            stringBuilder.append("  ");
            stringBuilder.append(event.getTargetState().name());

            Log.e(TAG, stringBuilder.toString());

            /**
             *  当没有create的时候，不可以调用destroy 不然会引发异常
             *  直接setCurrentState(DESTROYED) 会调用{@link LifecycleRegistry#moveToState(Lifecycle.State)}
             *  直至调用到{@link LifecycleRegistry#sync()} 进入其while分发事件。进入这个判断
             *  if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
             *                 backwardPass(lifecycleOwner);
             *   }
             *   这里拿到第一个监听器的状态，被认为是最新的状态值。这里取到的是INITIALIZED状态。
             *   而传入的状态为DESTROYED。根据compareTo对比，DESTROYED在INITIALIZED前面的状态，所以进行状态逆向更新
             *   调用了{@link LifecycleRegistry#backwardPass(LifecycleOwner)}
             *   做逆向更新状态，需要一步一步逆向，调用了{@link Lifecycle.Event#downFrom(Lifecycle.State)}
             *   返回了null.然后在{@link LifecycleRegistry#backwardPass(LifecycleOwner)}
             *   内部判断抛出了异常
             *   if (event == null) {
             *       throw new IllegalStateException("no event down from " + observer.mState);
             *    }
             *
             *   所以生命周期调用，就想想成一条有节点的流，只有顺时的流到达某种状态后，才能逆时回退。
             */

            if (event.getTargetState().isAtLeast(Lifecycle.State.CREATED)) {
                binding.btnOnDestroy.setVisibility(View.VISIBLE);
            } else {
                binding.btnOnDestroy.setVisibility(View.GONE);
            }

            if (event.getTargetState() == Lifecycle.State.DESTROYED) {
                removeMineLifeCycleObserver();
                mineLifecycleOwner = new MineLifecycleOwner();
            }
        }
    };


    public static class MineLifecycleOwner implements LifecycleOwner {

        private LifecycleRegistry registry;

        public MineLifecycleOwner() {
            registry = new LifecycleRegistry(this);
            registry.setCurrentState(Lifecycle.State.INITIALIZED);
        }

        public void onCreate() {
            registry.setCurrentState(Lifecycle.State.CREATED);
        }

        public void onStart() {
            registry.setCurrentState(Lifecycle.State.STARTED);
        }

        public void onResume() {
            registry.setCurrentState(Lifecycle.State.RESUMED);
        }

        public void onDestroy() {
            registry.setCurrentState(Lifecycle.State.DESTROYED);
        }

        @NonNull
        @Override
        public Lifecycle getLifecycle() {
            return registry;
        }
    }


    HashMap map = new HashMap();

    //这个例子是测试lambda时创建对象的问题。
    private void setClick() {
        //这种的，只会使用第一次创建的对象，不断set
        setClick((source, event) -> {

        });
        //这种，每次都会new一个新的对象进行set
        setClick(new LifecycleEventObserver() {
            @Override
            public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {

            }
        });

        Log.e(TAG, map.size() + " ");
    }

    public void setClick(LifecycleEventObserver click) {
        map.put(click, click);
    }
}
